iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Modern Web

剛入行就一人重新打造公司前端系統?系列 第 27

Day 27 - 儲存可變資料而不觸發重新渲染的 useRef

  • 分享至 

  • xImage
  •  

前幾篇文章都專注在 useState 與 useEffect 的討論,今天要來介紹 useRef。我在初學時總覺得 useRef 的概念很難理解,也搞不太懂使用情境,像許多功能用 useState 與 useRef 都可以實作,那到底差在哪呢,以下會來好好介紹~

useRef 基本介紹

useRef 是 React 中的一個 hook,用來存放「不會引發重新渲染的可變資料」,在 React.dev 的文件中,描述 useRef 時提到:

useRef is a React Hook that lets you reference a value that’s not needed for rendering.

裡面提到 useRef 是用來 參考(reference) 不需要被重新渲染的值。這是什麼意思呢?簡單來說, 參考 就是在記憶體中指向某個位置來保存資料。useRef 的作用是讓你在 React 元件中保留一塊資料,不論資料如何變動,都不會觸發畫面的重新渲染,而且在初始化過後,這個物件會始終指向同一個 參考

實務上來說,如果你有一些資料不影響畫面顯示,且只需在背後默默變更,那就可以使用 useRef。

語法:

const ref = useRef(initialValue);
  • initialValue:表示 current 的初始值。
  • useRef 會回傳一個物件,物件裡面只有一個屬性 current
  • 可以通過 ref.current 來讀取或修改資料,而不會觸發元件重新渲染。(與之相反,useState 的狀態變話會導致元件重新渲染)。

範例:

使用 useRef 來保存會變動的資料,而且不會觸發 React 的重新渲染。

import { useRef } from "react";

function MyComponent() {
  const countRef = useRef(0);  // 初始化 current 為 0

  const handleClick = () => {
    countRef.current += 1;  // 改變 current 值,不會觸發重新渲染
    console.log(countRef.current);  // 每次點擊顯示更新後的值
  };

  return (
    <div>
      <button onClick={handleClick}>點擊增加</button>
    </div>
  );
}

其他疑問:

初次碰到 useRef 時,光是看到語法的部分有超多疑問的,以下也列上 QA:

  • current 是什麼?可以存放什麼資料格式?

    useRef 回傳的物件內有一個屬性叫 current,這個屬性可以用來存放像是字串、物件、函式,但通常不會用來存放會影響渲染的狀態(這些通常由 useState 管理)。另外,也可以存放 DOM 元素的 reference。

  • 如何修改 current 的值?

    • 修改 ref.current 值的方法是直接操作 current 屬性,而不是整個 ref 物件。

使用情境上與 useState 的差別?

useState 的主要用途是管理狀態與畫面的更新,一旦 state 變化,React 就會重新渲染元件。而 useRef 內儲存的資料變化則不會觸發重新渲染。

簡單來說:

  • 如果你需要保存會影響 UI 更新的資料,選擇 useState。
  • 如果資料不需要導致重新渲染,選擇 useRef。

範例:input 框內的文字追蹤:該使用 useState 還是 useRef?

對於輸入框的文字追蹤,useStateuseRef 都可以做到,那到底該使用哪個呢?如果不需要即時顯示輸入內容,只需在某個時刻讀取或追蹤輸入值,可以用 useRef ,這樣可以避免不必要的重新渲染。

import { useRef } from "react";

function InputWithRef() {
  const inputRef = useRef('');

  const handleClick = () => {
    console.log(inputRef.current.value); // 讀取 input 值
  };

  return (
    <div className="App">
      <h1>useRef - searchbox</h1>
      <input ref={inputRef} type="text" />
      <button onClick={handleClick}>顯示輸入內容</button>
    </div>
  );
}

codesandbox

參考資料


上一篇
Day 26 - useState 的異步更新問題
下一篇
Day 28 - useCallback 到底是如何達到效能優化的目的?
系列文
剛入行就一人重新打造公司前端系統?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言